class Snake {
    // 蛇头
    head: HTMLElement
    // 蛇的身体包括蛇头
    bodies: HTMLCollection
    // 获取蛇的容器
    element: HTMLElement

    constructor() {
        this.element = document.getElementById('snake')!
        this.head = document.querySelector('#snake>div') as HTMLElement
        this.bodies = this.element.getElementsByTagName('div')
    }

    // 获取蛇的坐标，蛇头坐标
    get X() {
        return this.head.offsetLeft
    }

    get Y() {
        return this.head.offsetTop
    }

    // 设置
    set X(val) {
        if (this.X === val) {
            return
        }
        if (val < 0 || val > 290) {
            throw new Error('蛇撞墙了！')
        }
        // 修改X时，控制蛇左右移动，向左移动时不可向右
        if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetLeft === val) {
            if (val > this.X) {
                // 如果新值>val向右走，应继续向左
                val = this.X - 10
            } else {
                val = this.X + 10
            }
        }
        // 移动身体
        this.moveBody()
        this.head.style.left = val + 'px'
        // 检查撞击
        this.checkHeadBody()
    }

    set Y(val) {
        if (this.Y === val) {
            return
        }
        if (val < 0 || val > 290) {
            throw new Error('蛇撞墙了！')
        }
        if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop === val) {
            if (val > this.Y) {
                val = this.Y - 10
            } else {
                val = this.Y + 10
            }
        }
        // 移动身体
        this.moveBody()
        this.head.style.top = val + 'px'
        // 检查撞击
        this.checkHeadBody()
    }

    // 蛇增加身体长度
    addBody() {
        this.element.insertAdjacentHTML('beforeend', '<div></div>')
    }

    // 蛇身体移动
    moveBody() {
        /*
        * 将后边身体设置为前边身体的位置
        * */
        for (let i = this.bodies.length - 1; i > 0; i--) {
            // 获取前边身体的位置
            let X = (this.bodies[i - 1] as HTMLElement).offsetLeft;
            let Y = (this.bodies[i - 1] as HTMLElement).offsetTop;
            (this.bodies[i] as HTMLElement).style.left = X + 'px';
            (this.bodies[i] as HTMLElement).style.top = Y + 'px';

        }
    }

    // 蛇头是否撞到身体
    checkHeadBody() {
        // 获取所有的身体，检查是否和蛇头坐标重合
        for (let i = 1; i < this.bodies.length; i++) {
            let bd = this.bodies[i] as HTMLElement
            if (this.X === bd.offsetLeft && this.Y === bd.offsetTop) {
                throw new Error('撞到自己了！')
            }
        }
    }
}

export default Snake